﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using landlord2lib;
using landlord2.Properties;

namespace landlord2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private DispatcherTimer m_timer;
        private Sound m_sound;
        private DataSet m_dsPlayerInfo;
        private List<Card> m_handCards;
        private List<Card> m_lordCards;
        private DispatcherTimer m_clock;
        private volatile int m_clockTick;
        private ExtraWindow m_winExtra = new ExtraWindow();
        private bool m_onLoaded = false;
        private landlord2lib.CardGroup m_lastCardGroup;
        private HintCardCollection m_hint;
        private int m_clockMode;
        private int m_clockSeat;
        private int m_botPlayCount;

        public MainWindow()
        {
            InitializeComponent();

            m_timer = new DispatcherTimer();
            m_timer.Tick += Timer_Tick;
            m_timer.Interval = TimeSpan.FromSeconds(1);
            m_timer.Start();
            Title += " - " + GameClient.Current.Name;

            m_clock = new DispatcherTimer();
            m_clock.Tick += Clock_Tick;
            m_clock.Interval = TimeSpan.FromSeconds(2);

            GameClient.Current.OnPlayerInfo += OnPlayerInfo;
            GameClient.Current.OnPlayerReady += OnPlayerReady;
            GameClient.Current.OnGenerateCard += OnGenerateCards;
            GameClient.Current.OnCallLord += OnCallLord;
            GameClient.Current.OnCallLordResult += OnCallLordResult;
            GameClient.Current.OnGiveLordCard += OnGiveLordCard;
            GameClient.Current.OnShowLordCard += OnShowLordCard;
            GameClient.Current.OnSendCard += OnSendCard;
            GameClient.Current.OnSendCardResult += OnSendCardResult;
            GameClient.Current.OnGameResult += OnGameResult;
            GameClient.Current.OnRestartGame += OnRestartGame;
            GameClient.Current.OnOtherDisconnect += OnOtherDisconnect;
            GameClient.Current.OnSendChat += OnSendChat;
            GameClient.Current.OnRobotPlay += OnRobotPlay;

            GameClient.Current.Client.SetCurrentWindow(1);

            m_dsPlayerInfo = GameClient.Current.Client.GetPlayerInfo();
            ShowPlayerInfo(false);

            SetBackground(null);
            SetCardStyle(null);
            m_sound = new Sound();
            btnBGM.IsDown = !m_sound.EnableBGM;
            btnSE.IsDown = !m_sound.EnableSE;
            m_sound.PlayBGM(0);

            Step1();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            m_winExtra.Owner = this;
            m_winExtra.Show();
            m_onLoaded = true;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            if (GameClient.Current.Client != null) GameClient.Current.Client.HeartBeat();
        }

        private void SetBackground(int? bg)
        {
            if (bg == null) bg = Settings.Default.Background;
            Background = (ImageBrush)App.Current.Resources["Brush_Background" + (bg.Value + 1).ToString()];
        }

        private void SetCardStyle(int? style)
        {
            if (style == null) style = Settings.Default.CardStyle;
            HandCard1.CardStyle = style.Value;
            HandCard2.CardStyle = style.Value;
            HandCard3.CardStyle = style.Value;
            HandCard4.CardStyle = style.Value;
            LordCard.CardStyle = style.Value;
            LordCardBig.CardStyle = style.Value;
            OutCard1.CardStyle = style.Value;
            OutCard2.CardStyle = style.Value;
            OutCard3.CardStyle = style.Value;
            OutCard4.CardStyle = style.Value;
        }

        private void btnBGM_Down(object sender, DownEventArgs e)
        {
            m_sound.EnableBGM = !e.IsDown;
        }

        private void btnSE_Down(object sender, DownEventArgs e)
        {
            m_sound.EnableSE = !e.IsDown;
        }

        private void OnPlayerInfo(DataSet ds)
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                ShowPlayerInfo(false);
            });
        }

        private void ShowPlayerInfo(bool showCardCount)
        {
            m_winExtra.ShowPlayerInfo(m_dsPlayerInfo);
            lblPlayer1.Content = m_dsPlayerInfo.Tables[0].Rows[GameClient.Current.PosToSeat(0)]["Name"].ToString();
            lblPlayer2.Content = m_dsPlayerInfo.Tables[0].Rows[GameClient.Current.PosToSeat(1)]["Name"].ToString();
            lblPlayer3.Content = m_dsPlayerInfo.Tables[0].Rows[GameClient.Current.PosToSeat(2)]["Name"].ToString();
            lblPlayer4.Content = m_dsPlayerInfo.Tables[0].Rows[GameClient.Current.PosToSeat(3)]["Name"].ToString();
            if (showCardCount)
            {
                lblPlayer1.Content = lblPlayer1.Content.ToString() + " / 剩余 " + HandCard1.GetCardCount() + " 张牌";
                lblPlayer2.Content = lblPlayer2.Content.ToString() + " / 剩余 " + HandCard2.GetCardCount() + " 张牌";
                lblPlayer3.Content = lblPlayer3.Content.ToString() + " / 剩余 " + HandCard3.GetCardCount() + " 张牌";
                lblPlayer4.Content = lblPlayer4.Content.ToString() + " / 剩余 " + HandCard4.GetCardCount() + " 张牌";
            }
        }

        private void Step1()
        {
            btnReady.Visibility = Visibility.Visible;
            btnCallLord1.Visibility = Visibility.Collapsed;
            btnCallLord2.Visibility = Visibility.Collapsed;
            btnCallLord3.Visibility = Visibility.Collapsed;
            btnNoCallLord.Visibility = Visibility.Collapsed;
            btnTake.Visibility = Visibility.Collapsed;
            imgPlayer1.Visibility = Visibility.Collapsed;
            imgPlayer2.Visibility = Visibility.Collapsed;
            imgPlayer3.Visibility = Visibility.Collapsed;
            imgPlayer4.Visibility = Visibility.Collapsed;
            HandCard1.Visibility = Visibility.Collapsed;
            HandCard2.Visibility = Visibility.Collapsed;
            HandCard3.Visibility = Visibility.Collapsed;
            HandCard4.Visibility = Visibility.Collapsed;
            LordCard.Visibility = Visibility.Collapsed;
            LordCard.Visibility = Visibility.Collapsed;
            imgLord1.Visibility = Visibility.Collapsed;
            imgLord2.Visibility = Visibility.Collapsed;
            imgLord3.Visibility = Visibility.Collapsed;
            imgLord4.Visibility = Visibility.Collapsed;
            lblPoint.Visibility = Visibility.Collapsed;
            btnClearSel.Visibility = Visibility.Collapsed;
            btnSend.Visibility = Visibility.Collapsed;
            btnPass.Visibility = Visibility.Collapsed;
            btnHint.Visibility = Visibility.Collapsed;
            OutCard1.Visibility = Visibility.Collapsed;
            OutCard2.Visibility = Visibility.Collapsed;
            OutCard3.Visibility = Visibility.Collapsed;
            OutCard4.Visibility = Visibility.Collapsed;
            imgChat1.Visibility = Visibility.Collapsed;
            imgChat2.Visibility = Visibility.Collapsed;
            imgChat3.Visibility = Visibility.Collapsed;
            imgChat4.Visibility = Visibility.Collapsed;
            imgClock1.Visibility = Visibility.Collapsed;
            imgClock2.Visibility = Visibility.Collapsed;
            imgClock3.Visibility = Visibility.Collapsed;
            imgClock4.Visibility = Visibility.Collapsed;
        }

        private void btnReady_Click(object sender, RoutedEventArgs e)
        {
            m_sound.PlaySE(3);
            btnReady.Visibility = Visibility.Collapsed;
            GameClient.Current.Client.SetReady();
        }

        private void OnPlayerReady(int seat)
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                int pos = GameClient.Current.SeatToPos(seat);
                switch (pos)
                {
                    case 0:
                        imgPlayer1.Style = (Style)App.Current.Resources["ReadyStyle"];
                        imgPlayer1.Visibility = Visibility.Visible;
                        break;
                    case 1:
                        imgPlayer2.Style = (Style)App.Current.Resources["ReadyStyle"];
                        imgPlayer2.Visibility = Visibility.Visible;
                        break;
                    case 2:
                        imgPlayer3.Style = (Style)App.Current.Resources["ReadyStyle"];
                        imgPlayer3.Visibility = Visibility.Visible;
                        break;
                    case 3:
                        imgPlayer4.Style = (Style)App.Current.Resources["ReadyStyle"];
                        imgPlayer4.Visibility = Visibility.Visible;
                        break;
                }
            });
        }

        private void Step2()
        {
            m_sound.PlayBGM(m_sound.BGM);

            imgPlayer1.Visibility = Visibility.Collapsed;
            imgPlayer2.Visibility = Visibility.Collapsed;
            imgPlayer3.Visibility = Visibility.Collapsed;
            imgPlayer4.Visibility = Visibility.Collapsed;
            HandCard1.ClearCards();
            HandCard2.ClearCards();
            HandCard3.ClearCards();
            HandCard4.ClearCards();
            HandCard1.Visibility = Visibility.Visible;
            HandCard2.Visibility = Visibility.Visible;
            HandCard3.Visibility = Visibility.Visible;
            HandCard4.Visibility = Visibility.Visible;
        }

        private void OnGenerateCards(Card[] cards)
        {
            m_handCards = new List<Card>(cards);
            Queue<Card> queueCards = new Queue<Card>(cards);
            Dispatcher.BeginInvoke((Action)delegate()
            {
                Step2();
                m_sound.PlaySE(0);
                new Task(() =>
                {
                    int count = 25;
                    while (count > 0)
                    {
                        Dispatcher.BeginInvoke((Action)delegate()
                        {
                            for (int i = 0; i < 2; i++)
                            {
                                if (queueCards.Count > 0)
                                {
                                    HandCard1.AddCard(queueCards.Dequeue());
                                    HandCard2.AddCards(1);
                                    HandCard3.AddCards(1);
                                    HandCard4.AddCards(1);
                                    count--;
                                }
                            }
                            ShowPlayerInfo(true);
                        });
                        Thread.Sleep(300);
                    }
                    Thread.Sleep(1000);
                    HandCard1.SortCard(Settings.Default.CardSortMode);
                    Thread.Sleep(500);
                    Dispatcher.BeginInvoke((Action)delegate()
                    {
                        m_sound.PlaySE(1);
                    });
                }).Start();
            });
        }

        private void OnCallLord(int seat, int call)
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                if (seat == GameClient.Current.Seat.Value)
                {
                    btnCallLord1.Visibility = Visibility.Visible;
                    btnCallLord2.Visibility = Visibility.Visible;
                    btnCallLord3.Visibility = Visibility.Visible;
                    btnNoCallLord.Visibility = Visibility.Visible;
                    int jokerCount = 0;
                    foreach (Card card in m_handCards)
                    {
                        if (card.IsJoker) jokerCount++;
                    }
                    if (jokerCount >= 2)
                    {
                        btnCallLord1.IsEnabled = false;
                        btnCallLord2.IsEnabled = false;
                        btnCallLord3.IsEnabled = true;
                        btnNoCallLord.IsEnabled = false;
                    }
                    else
                    {
                        btnCallLord1.IsEnabled = call == 0;
                        btnCallLord2.IsEnabled = call <= 1;
                        btnCallLord3.IsEnabled = true;
                        btnNoCallLord.IsEnabled = true;
                    }
                }
                Image img = null;
                switch (GameClient.Current.SeatToPos(seat))
                {
                    case 0: img = imgClock1; break;
                    case 1: img = imgClock2; break;
                    case 2: img = imgClock3; break;
                    case 3: img = imgClock4; break;
                }
                img.Style = (Style)App.Current.Resources["ClockStyle"];
                img.Source = (ImageSource)App.Current.Resources["Clock30"];
                img.Visibility = Visibility.Visible;
                m_clockSeat = seat;
                m_clockMode = 0;
                m_clockTick = 30;
                m_clock.Start();
            });
        }

        private void btnCallLord_Click(object sender, RoutedEventArgs e)
        {
            m_sound.PlaySE(3);
            int call = 0;
            if (sender == btnCallLord1) call = 1;
            else if (sender == btnCallLord2) call = 2;
            else if (sender == btnCallLord3) call = 3;
            GameClient.Current.Client.CallLord(call);
            btnCallLord1.Visibility = Visibility.Collapsed;
            btnCallLord2.Visibility = Visibility.Collapsed;
            btnCallLord3.Visibility = Visibility.Collapsed;
            btnNoCallLord.Visibility = Visibility.Collapsed;
        }

        private void OnCallLordResult(int seat, int call)
        {
            int gender = GetPlayerGender(seat);
            Dispatcher.BeginInvoke((Action)delegate()
            {
                if (call != 0) m_sound.PlayVoice(gender, 41);
                else m_sound.PlayVoice(gender, 42);
                Style style = call != 0 ? (Style)App.Current.Resources["CallStyle"] : (Style)App.Current.Resources["NoCallStyle"];
                switch (GameClient.Current.SeatToPos(seat))
                {
                    case 0:
                        imgPlayer1.Style = style;
                        imgPlayer1.Visibility = Visibility.Visible;
                        imgClock1.Visibility = Visibility.Collapsed;
                        break;
                    case 1:
                        imgPlayer2.Style = style;
                        imgPlayer2.Visibility = Visibility.Visible;
                        imgClock2.Visibility = Visibility.Collapsed;
                        break;
                    case 2:
                        imgPlayer3.Style = style;
                        imgPlayer3.Visibility = Visibility.Visible;
                        imgClock3.Visibility = Visibility.Collapsed;
                        break;
                    case 3:
                        imgPlayer4.Style = style;
                        imgPlayer4.Visibility = Visibility.Visible;
                        imgClock4.Visibility = Visibility.Collapsed;
                        break;
                }
            });
        }

        private int GetPlayerGender(int seat)
        {
            return Convert.ToInt32(m_dsPlayerInfo.Tables[0].Rows[seat]["Gender"]);
        }

        private void OnGiveLordCard(Card[] cards, int point)
        {
            OnShowLordCard(GameClient.Current.Seat.Value, cards, point);
            Dispatcher.BeginInvoke((Action)delegate()
            {
                HandCard1.AddCards(cards);
                ShowPlayerInfo(true);
                new Task(() =>
                {
                    Thread.Sleep(1000);
                    HandCard1.SortCard(Settings.Default.CardSortMode);
                }).Start();
            });
        }

        private void OnShowLordCard(int seat, Card[] cards, int point)
        {
            m_lordCards = new List<Card>(cards);
            Dispatcher.BeginInvoke((Action)delegate()
            {
                imgPlayer1.Visibility = Visibility.Collapsed;
                imgPlayer2.Visibility = Visibility.Collapsed;
                imgPlayer3.Visibility = Visibility.Collapsed;
                imgPlayer4.Visibility = Visibility.Collapsed;
                lblPoint.Content = "底分: " + point.ToString();
                lblPoint.Visibility = Visibility.Visible;
                LordCard.ClearCards();
                LordCard.AddCards(cards);
                LordCard.QuickSortCard(1);
                LordCard.Visibility = Visibility.Visible;
                LordCardBig.ClearCards();
                LordCardBig.AddCards(cards);
                LordCardBig.QuickSortCard(1);
                LordCardBig.Visibility = Visibility.Visible;
                ThicknessAnimation thickAnim = new ThicknessAnimation(new Thickness(), new Duration(TimeSpan.FromMilliseconds(200)), FillBehavior.Stop);
                Storyboard.SetTargetProperty(thickAnim, new PropertyPath("Margin"));
                switch (GameClient.Current.SeatToPos(seat))
                {
                    case 0:
                        imgLord1.Visibility = Visibility.Visible;
                        thickAnim.To = new Thickness(0, 478, 0, 0);
                        break;
                    case 1:
                        HandCard2.AddCards(8);
                        imgLord2.Visibility = Visibility.Visible;
                        thickAnim.To = new Thickness(896, 258, 22, 0);
                        break;
                    case 2:
                        HandCard3.AddCards(8);
                        imgLord3.Visibility = Visibility.Visible;
                        thickAnim.To = new Thickness(0, 24, 0, 0);
                        break;
                    case 3:
                        HandCard4.AddCards(8);
                        imgLord4.Visibility = Visibility.Visible;
                        thickAnim.To = new Thickness(23, 258, 895, 0);
                        break;
                }
                ShowPlayerInfo(true);

                Storyboard story = ((Storyboard)App.Current.Resources["Storyboard_LordCard"]).Clone();
                story.Children.Add(thickAnim);
                story.Completed += delegate(object sender, EventArgs e)
                {
                    LordCardBig.Visibility = Visibility.Collapsed;
                };
                LordCardBig.BeginStoryboard(story);
            });
        }

        private void btnClearSel_Click(object sender, RoutedEventArgs e)
        {
            m_sound.PlaySE(3);
            HandCard1.ClearSelect();
        }

        private void btnSend_Click(object sender, RoutedEventArgs e)
        {
            m_botPlayCount = 0;
            m_sound.PlaySE(3);
            SendCard();
        }

        private bool SendCard()
        {
            List<Card> cards = new List<Card>(HandCard1.GetSelectedCards());
            if (GameClient.Current.Client.SendCard(cards.ToArray(), HandCard1.GetCardCount() == cards.Count))
            {
                HandCard1.RemoveCards(cards);
                HandCard1.QuickSortCard(Settings.Default.CardSortMode);
                
                m_sound.PlaySE(2);
                btnClearSel.Visibility = Visibility.Collapsed;
                btnSend.Visibility = Visibility.Collapsed;
                btnPass.Visibility = Visibility.Collapsed;
                btnHint.Visibility = Visibility.Collapsed;
                m_hint = null;
                return true;
            }
            return false;
        }

        private void btnPass_Click(object sender, RoutedEventArgs e)
        {
            m_botPlayCount = 0;
            m_sound.PlaySE(3);
            PassCard();
        }

        private bool PassCard()
        {
            if (GameClient.Current.Client.SendCard(null, false))
            {
                btnClearSel.Visibility = Visibility.Collapsed;
                btnSend.Visibility = Visibility.Collapsed;
                btnPass.Visibility = Visibility.Collapsed;
                btnHint.Visibility = Visibility.Collapsed;
                m_hint = null;
                return true;
            }
            return false;
        }

        private void OnSendCard(int seat)
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                if (seat == GameClient.Current.Seat.Value)
                {
                    btnClearSel.Visibility = Visibility.Visible;
                    btnSend.Visibility = Visibility.Visible;
                    btnPass.Visibility = Visibility.Visible;
                    btnHint.Visibility = Visibility.Visible;
                }
                Image img = null;
                switch (GameClient.Current.SeatToPos(seat))
                {
                    case 0:
                        imgPlayer1.Visibility = Visibility.Collapsed;
                        OutCard1.Visibility = Visibility.Collapsed;
                        img = imgClock1;
                        break;
                    case 1:
                        imgPlayer2.Visibility = Visibility.Collapsed;
                        OutCard2.Visibility = Visibility.Collapsed;
                        img = imgClock2;
                        break;
                    case 2:
                        imgPlayer3.Visibility = Visibility.Collapsed;
                        OutCard3.Visibility = Visibility.Collapsed;
                        img = imgClock3;
                        break;
                    case 3:
                        imgPlayer4.Visibility = Visibility.Collapsed;
                        OutCard4.Visibility = Visibility.Collapsed;
                        img = imgClock4;
                        break;
                }
                img.Style = (Style)App.Current.Resources["ClockStyle"];
                img.Source = (ImageSource)App.Current.Resources["Clock30"];
                img.Visibility = Visibility.Visible;
                m_clockSeat = seat;
                m_clockMode = 1;
                m_clockTick = 30;
                m_clock.Start();
                if (btnRobot.IsDown && seat == GameClient.Current.Seat.Value)
                {
                    new Task(() =>
                    {
                        Thread.Sleep(200);
                        Dispatcher.BeginInvoke((Action)delegate()
                        {
                            BotPlay(false);
                        });
                    }).Start();
                }
            });
        }

        private void OnSendCardResult(int seat, Card[] cards, bool bigger)
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                m_clock.Stop();
                imgClock1.Visibility = Visibility.Collapsed;
                imgClock2.Visibility = Visibility.Collapsed;
                imgClock3.Visibility = Visibility.Collapsed;
                imgClock4.Visibility = Visibility.Collapsed;
            });

            if (cards == null)
            {
                Dispatcher.BeginInvoke((Action)delegate()
                {
                    Random rand = new Random();
                    int se = rand.Next(34, 38);
                    m_sound.PlayVoice(GetPlayerGender(seat), se);

                    int pos = GameClient.Current.SeatToPos(seat);
                    Image img = null;
                    switch (pos)
                    {
                        case 0:
                            img = imgPlayer1;
                            OutCard1.Visibility = Visibility.Collapsed;
                            break;
                        case 1:
                            img = imgPlayer2;
                            OutCard2.Visibility = Visibility.Collapsed;
                            break;
                        case 2:
                            img = imgPlayer3;
                            OutCard3.Visibility = Visibility.Collapsed;
                            break;
                        case 3:
                            img = imgPlayer4;
                            OutCard4.Visibility = Visibility.Collapsed;
                            break;
                    }
                    img.Style = (Style)App.Current.Resources["PassStyle"];
                    img.Visibility = Visibility.Visible;
                });
            }
            else
            {
                landlord2lib.CardGroup group = landlord2lib.CardGroup.AssignCardGroup(cards);
                m_lastCardGroup = group;
                int? se = null, se2 = null, se3 = null;
                if (bigger)
                {
                    Random rand = new Random();
                    se = rand.Next(38, 41);
                    if (group != null && group is CardGroupBoom) se2 = 4;
                }
                else
                {
                    if (group != null)
                    {
                        if (group is CardGroupSingle)
                        {
                            switch (cards[0].Point)
                            {
                                case CardPoint.CardA: se = 0; break;
                                case CardPoint.Card2: se = 1; break;
                                case CardPoint.Card3: se = 2; break;
                                case CardPoint.Card4: se = 3; break;
                                case CardPoint.Card5: se = 4; break;
                                case CardPoint.Card6: se = 5; break;
                                case CardPoint.Card7: se = 6; break;
                                case CardPoint.Card8: se = 7; break;
                                case CardPoint.Card9: se = 8; break;
                                case CardPoint.Card10: se = 9; break;
                                case CardPoint.CardJ: se = 10; break;
                                case CardPoint.CardQ: se = 11; break;
                                case CardPoint.CardK: se = 12; break;
                                case CardPoint.CardGJoker: se = 13; break;
                                case CardPoint.CardJoker: se = 14; break;
                            }
                        }
                        else if (group is CardGroupPair)
                        {
                            switch (cards[0].Point)
                            {
                                case CardPoint.CardA: se = 15; break;
                                case CardPoint.Card2: se = 16; break;
                                case CardPoint.Card3: se = 17; break;
                                case CardPoint.Card4: se = 18; break;
                                case CardPoint.Card5: se = 19; break;
                                case CardPoint.Card6: se = 20; break;
                                case CardPoint.Card7: se = 21; break;
                                case CardPoint.Card8: se = 22; break;
                                case CardPoint.Card9: se = 23; break;
                                case CardPoint.Card10: se = 24; break;
                                case CardPoint.CardJ: se = 25; break;
                                case CardPoint.CardQ: se = 26; break;
                                case CardPoint.CardK: se = 27; break;
                            }
                        }
                        else if (group is CardGroupTriple)
                        {
                            se3 = 28;
                            switch (cards[0].Point)
                            {
                                case CardPoint.CardA: se = 0; break;
                                case CardPoint.Card2: se = 1; break;
                                case CardPoint.Card3: se = 2; break;
                                case CardPoint.Card4: se = 3; break;
                                case CardPoint.Card5: se = 4; break;
                                case CardPoint.Card6: se = 5; break;
                                case CardPoint.Card7: se = 6; break;
                                case CardPoint.Card8: se = 7; break;
                                case CardPoint.Card9: se = 8; break;
                                case CardPoint.Card10: se = 9; break;
                                case CardPoint.CardJ: se = 10; break;
                                case CardPoint.CardQ: se = 11; break;
                                case CardPoint.CardK: se = 12; break;
                            }
                        }
                        else if (group is CardGroupGourd) se = 29;
                        else if (group is CardGroupProgressPair || group is CardGroupProgressTriple) se = 30;
                        else if (group is CardGroupButterfly) se = 31;
                        else if (group is CardGroupBoom)
                        {
                            se = 32;
                            if (cards.Length >= 6) se2 = 5;
                            else se2 = 4;
                        }
                        else
                        {
                            se = 33;
                            se2 = 5;
                        }
                    }
                }

                Dispatcher.BeginInvoke((Action)delegate()
                {
                    if (se != null)
                    {
                        if (se2 != null)
                        {
                            m_sound.PlayVoice(GetPlayerGender(seat), se.Value);
                            m_sound.PlaySE(se2.Value);
                        }
                        else if (se3 != null)
                        {
                            new Task(() =>
                            {
                                Dispatcher.BeginInvoke((Action)delegate()
                                {
                                    m_sound.PlayVoice(GetPlayerGender(seat), se3.Value);
                                });
                                Thread.Sleep(GetPlayerGender(seat) == 0 ? 400 : 500);
                                Dispatcher.BeginInvoke((Action)delegate()
                                {
                                    m_sound.PlayVoice(GetPlayerGender(seat), se.Value);
                                });
                            }).Start();
                        }
                        else m_sound.PlayVoice(GetPlayerGender(seat), se.Value);
                    }

                    int pos = GameClient.Current.SeatToPos(seat);
                    CardGroup cardGroup = null;
                    switch (pos)
                    {
                        case 0:
                            cardGroup = OutCard1;
                            imgPlayer1.Visibility = Visibility.Collapsed;
                            break;
                        case 1:
                            cardGroup = OutCard2;
                            imgPlayer2.Visibility = Visibility.Collapsed;
                            HandCard2.RemoveCards(cards.Length);
                            break;
                        case 2:
                            cardGroup = OutCard3;
                            imgPlayer3.Visibility = Visibility.Collapsed;
                            HandCard3.RemoveCards(cards.Length);
                            break;
                        case 3:
                            cardGroup = OutCard4;
                            imgPlayer4.Visibility = Visibility.Collapsed;
                            HandCard4.RemoveCards(cards.Length);
                            break;
                    }
                    if (cardGroup != null)
                    {
                        cardGroup.ClearCards();
                        cardGroup.AddCards(cards);
                        cardGroup.QuickSortCard(1);
                        cardGroup.Visibility = Visibility.Visible;
                    }
                    ShowPlayerInfo(true);
                });
            }
        }

        private void HandCard1_ItemRightClick(object sender, RoutedEventArgs e)
        {
            if (btnSend.Visibility == Visibility.Visible) btnSend_Click(btnSend, e);
        }

        private void OnGameResult(DataSet ds, bool win)
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                m_sound.PlayResult(win);

                for (int i = 0; i < m_dsPlayerInfo.Tables[0].Rows.Count; i++)
                    m_dsPlayerInfo.Tables[0].Rows[i]["Point"] = Convert.ToInt32(ds.Tables[0].Rows[i]["Point"]);
                ShowPlayerInfo(false);

                GameResultWindow window = new GameResultWindow();
                window.Owner = this;
                window.SetGameResult(ds);
                window.Show();
            });
        }

        private void OnRestartGame()
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                Step1();
                m_handCards = null;
                m_lordCards = null;
                m_lastCardGroup = null;
                m_hint = null;
                m_clockMode = 0;
                m_clockSeat = 0;
                m_botPlayCount = 0;
                btnRobot.IsDown = false;
            });
        }

        private void OnOtherDisconnect()
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                MessageBox.Show("有玩家退出游戏或掉线，游戏退出！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                App.Current.Shutdown();
            });
        }

        private void btnOption_Click(object sender, RoutedEventArgs e)
        {
            OptionWindow window = new OptionWindow();
            window.Owner = this;
            window.OnApplySetting += OptionWindow_ApplySetting;
            window.Show();
        }

        private void OptionWindow_ApplySetting(object sender, EventArgs e)
        {
            OptionWindow window = (OptionWindow)sender;
            int oldCardStyle = Settings.Default.CardStyle;
            int oldBackground = Settings.Default.Background;
            int oldBGM = Settings.Default.BGM;
            int cardSortMode = Settings.Default.CardSortMode;

            Settings.Default.CardStyle = window.CardStyle;
            Settings.Default.Background = window.BackgroundIndex;
            Settings.Default.BGM = window.BGM;
            Settings.Default.CardSortMode = window.CardSortMode;
            Settings.Default.Save();

            if (oldCardStyle != window.CardStyle) SetCardStyle(window.CardStyle);
            if (oldBackground != window.BackgroundIndex) SetBackground(window.BackgroundIndex);
            if (oldBGM != window.BGM) m_sound.BGM = window.BGM;
            if (cardSortMode != window.CardSortMode) HandCard1.QuickSortCard(window.CardSortMode);
        }

        private void OnSendChat(int seat, int gender, int index)
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                m_sound.PlayChat(gender, index);
                int pos = GameClient.Current.SeatToPos(seat);
                Image img = null;
                switch (pos)
                {
                    case 0: img = imgChat1; break;
                    case 1: img = imgChat2; break;
                    case 2: img = imgChat3; break;
                    case 3: img = imgChat4; break;
                }
                img.Visibility = Visibility.Visible;
                new Task(() =>
                {
                    Thread.Sleep(3000);
                    Dispatcher.BeginInvoke((Action)delegate()
                    {
                        img.Visibility = Visibility.Collapsed;
                    });
                }).Start();
            });
        }

        private void btnChat_Click(object sender, RoutedEventArgs e)
        {
            mnuChat.PlacementTarget = btnChat;
            mnuChat.Placement = System.Windows.Controls.Primitives.PlacementMode.Top;
            mnuChat.IsOpen = true;
        }

        private void btnChat_Initialized(object sender, EventArgs e)
        {
            btnChat.ContextMenu = null;
        }

        private void mnuChat_Item_Click(object sender, RoutedEventArgs e)
        {
            int index = mnuChat.Items.IndexOf(sender);
            GameClient.Current.Client.SendChat(GameClient.Current.Gender, index);
        }

        private void Clock_Tick(object sender, EventArgs e)
        {
            int seat = m_clockSeat;
            if (m_clockTick == 0)
            {
                m_clock.Stop();
                if (seat == GameClient.Current.Seat.Value)
                {
                    switch (m_clockMode)
                    {
                        case 0:
                            if (btnNoCallLord.IsEnabled) btnCallLord_Click(btnNoCallLord, null);
                            else if (btnCallLord1.IsEnabled) btnCallLord_Click(btnCallLord1, null);
                            else if (btnCallLord2.IsEnabled) btnCallLord_Click(btnCallLord2, null);
                            else if (btnCallLord3.IsEnabled) btnCallLord_Click(btnCallLord3, null);
                            break;
                        case 1:
                            BotPlay(false);
                            break;
                    }
                }
            }
            else
            {
                m_clockTick--;
                Image img = null;
                switch (GameClient.Current.SeatToPos(seat))
                {
                    case 0: img = imgClock1; break;
                    case 1: img = imgClock2; break;
                    case 2: img = imgClock3; break;
                    case 3: img = imgClock4; break;
                }
                img.Source = (ImageSource)App.Current.Resources[string.Format("Clock{0:00}", m_clockTick)];
                if (m_clockTick == 10) m_sound.PlaySE(6);
            }
        }

        private void Window_LocationChanged(object sender, EventArgs e)
        {
            if (m_onLoaded) m_winExtra.Reposition();
        }

        private void btnHint_Click(object sender, RoutedEventArgs e)
        {
            if (m_lastCardGroup != null)
            {
                if (m_hint == null) m_hint = landlord2lib.CardGroup.Hint(HandCard1.GetCards(), m_lastCardGroup);
                Card[] cards = m_hint.NextHintLoop();
                if (cards != null) HandCard1.SetSelectedCards(cards);
            }
        }

        private void BotPlay(bool manual)
        {
            if (!manual)
            {
                m_botPlayCount++;
                if (m_botPlayCount == 3) btnRobot.IsDown = true;
            }
            if (PassCard()) return;
            Card[] cards = HandCard1.GetCards();
            HandCard1.SetSelectedCards(new Card[] { cards[cards.Length - 1] });
            SendCard();
        }

        private void btnRobot_Down(object sender, DownEventArgs e)
        {
            GameClient.Current.Client.RobotPlay(e.IsDown);
            if (e.IsDown && btnSend.Visibility == Visibility.Visible)
            {
                new Task(() =>
                {
                    Thread.Sleep(200);
                    Dispatcher.BeginInvoke((Action)delegate()
                    {
                        BotPlay(true);
                    });
                }).Start();
            }
        }

        private void OnRobotPlay(int seat, bool ena)
        {
            Dispatcher.BeginInvoke((Action)delegate()
            {
                switch (GameClient.Current.SeatToPos(seat))
                {
                    case 0: imgRobot1.Visibility = ena ? Visibility.Visible : Visibility.Collapsed; break;
                    case 1: imgRobot2.Visibility = ena ? Visibility.Visible : Visibility.Collapsed; break;
                    case 2: imgRobot3.Visibility = ena ? Visibility.Visible : Visibility.Collapsed; break;
                    case 3: imgRobot4.Visibility = ena ? Visibility.Visible : Visibility.Collapsed; break;
                }
            });
        }
    }
}
